package com;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

import struct.ItemInfo;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;



@SuppressWarnings("serial")
public class SearchServlet extends HttpServlet 
{//client-server style (get input from client, then redirect output)
	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException, ServletException 
	{
		String input = req.getParameter("input");
		String category = req.getParameter("category");
		String username = req.getParameter("username");
		
		req.setAttribute("username", username);
		
		if (category.equals("recommended"))//recommended button pressed
		{
			req.setAttribute("itemList", GetRecommendedItems(username));
		}
		else
		{
			if (category.equals("none")){//search button pressed
				req.setAttribute("itemList", GetSearchData(input));
			}else{//category button pressed
				req.setAttribute("itemList", GetTestData(category));
			}
		}
				
		req.getRequestDispatcher("itemList.jsp").forward(req, resp);
	}
	
	public ArrayList<ItemInfo> GetRecommendedItems(String username)
	{
		// categories are either games, music, or other
		// get most recently bidded item's category name;
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		String itemID="";
		
		
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		
		Query qBids = new Query("Bid").addFilter("BIDDER",  FilterOperator.EQUAL, username).addSort("TIME", Query.SortDirection.DESCENDING);//descneding for the latest bid
		Iterable<Entity> bids = ds.prepare(qBids).asIterable();
		for(Entity bid : bids ){
			//get the latest bid by the user, then exit the loop
			itemID = (String) bid.getProperty("ITEMID");
			//System.out.println(itemID);
			//System.out.println(bid.getProperty("TIME"));
			break;
		}
		
		Entity e;
		try {
			e = ds.get(KeyFactory.createKey("Auction", Integer.parseInt(itemID)));
			
			Boolean match;
			
			String nameSearch=(String) e.getProperty("NAME");
			String descriptionSearch = (String) e.getProperty("DESCRIPTION");
			String categorySearch = (String) e.getProperty("CATEGORY");
			
			if(categorySearch == null){categorySearch ="nothing";}//temporary work around a non up-to-date db
			
			String[] flds1 = nameSearch.split(" ");
			String[] flds2 = descriptionSearch.split(" ");
			String[] flds3 = categorySearch.split(" ");
							
			String name;
			String description;
			String category;

			//get all auctions 
					Query qAuctions = new Query("Auction");
					Iterable<Entity> auctions = ds.prepare(qAuctions).asIterable();
					for(Entity auction : auctions )
					{
						match = false;
						
						name = (String) auction.getProperty("NAME");
						description = (String) auction.getProperty("DESCRIPTION");
						category = (String) auction.getProperty("CATEGORY");
						
						if(category == null){category ="none";}//temporary work around a non up-to-date db
						
						for(int i = 0 ; i < flds1.length ; i++){//check for match name
							if(name.toLowerCase().contains(flds1[i].toLowerCase()) ||
							   description.toLowerCase().contains(flds1[i].toLowerCase()) ||
							   category.toLowerCase().contains(flds1[i].toLowerCase()) ){
								match = true;
								break;
							}
							//do nothing
						}
						for(int i = 0 ; i < flds2.length ; i++){//check for match description
							if(name.toLowerCase().contains(flds2[i].toLowerCase()) ||
							   description.toLowerCase().contains(flds2[i].toLowerCase()) ||
							   category.toLowerCase().contains(flds2[i].toLowerCase()) ){
								match = true;
								break;
							}
							//do nothing
						}
						for(int i = 0 ; i < flds3.length ; i++){//check for match category
							if(name.toLowerCase().contains(flds3[i].toLowerCase()) ||
							   description.toLowerCase().contains(flds3[i].toLowerCase()) ||
							   category.toLowerCase().contains(flds3[i].toLowerCase()) ){
								match = true;
								break;
							}
							//do nothing
						}
						
						if(match){
									
									ItemInfo item = new ItemInfo();
									String start = "";
									String end = "";
									String current="";
									java.util.Date d1,d2,d3;
									long minutes=-1;
									long hours=-1;
									long days=-1;
									double currBid;
									
									DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm");
									
									java.util.Date currentDate = new java.util.Date();	
									current = df.format(currentDate);
									
								
									item.itemID = auction.getKey().getId();
									//System.out.println(item.itemID);
						
									item.description = (String) auction.getProperty("DESCRIPTION");
													
									
									item.itemName = (String) auction.getProperty("NAME");
									//System.out.println(item.itemName);
									
									
									//get highest bid 
									Query qqBids = new Query("Bid").addFilter("ITEMID", FilterOperator.EQUAL, Long.toString(item.itemID) );
									Iterable<Entity> bbids = ds.prepare(qqBids).asIterable();
									double maxBid =Double.parseDouble(auction.getProperty("PRICE").toString());
									for(Entity bbid : bbids )
									{
										currBid = (Double) bbid.getProperty("OFFER");
										if(currBid > maxBid){
											maxBid = currBid;
										}
									}
									item.currentBid = maxBid;
									
									
									start =  (String) auction.getProperty("START");
									end =  (String) auction.getProperty("END");
									try {
										
										
										d1 = df.parse(start);
										d2 = df.parse(end);
										d3 = df.parse(current);
										
										 if (d3.after(d2)){
												//do not display, expired
										}else if(d3.before(d1)){
											minutes = (d2.getTime()-d1.getTime())/(1000*60)%60;
											hours = (d2.getTime()-d1.getTime())/(1000*60*60)%24;
											days = (d2.getTime()-d1.getTime())/(1000*60*60*24);
											item.timeLeft = (days + "d" + hours + "h" +minutes+"m");
											
											item.img = "ta1.jpg";
											item.seller = (String) auction.getProperty("SELLER");
											
											list.add(item);
						
										}else{
											minutes = (d2.getTime()-d3.getTime())/(1000*60)%60;
											hours = (d2.getTime()-d3.getTime())/(1000*60*60)%24;
											days = (d2.getTime()-d3.getTime())/(1000*60*60*24);
											item.timeLeft = (days + "d" + hours + "h" +minutes+"m");
											
											item.img = "ta1.jpg";
											item.seller = (String) auction.getProperty("SELLER");
											
											list.add(item);
						
										}
										
									} catch (ParseException ex) {
										// TODO Auto-generated catch block
										ex.printStackTrace();
									}
						}	
					}
		
		} catch (NumberFormatException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (EntityNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		
		return list;
	}
	
	public ArrayList<ItemInfo> GetSearchData(String input) {
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		Boolean match;
		
		String name="";
		String description = "";
		String category = "";
		
		String[] flds = input.split(" ");
		
		//get all auctions 
		Query qAuctions = new Query("Auction");
		Iterable<Entity> auctions = ds.prepare(qAuctions).asIterable();
		for(Entity auction : auctions )
		{
			match = false;
			
			name = (String) auction.getProperty("NAME");
			description = (String) auction.getProperty("DESCRIPTION");
			category = (String) auction.getProperty("CATEGORY");
			
			if(category == null){category ="none";}//temporary work around a non up-to-date db
			
			for(int i = 0 ; i < flds.length ; i++){//check for match
				if(name.toLowerCase().contains(flds[i].toLowerCase()) ||
				   description.toLowerCase().contains(flds[i].toLowerCase()) ||
				   category.toLowerCase().contains(flds[i].toLowerCase()) ){
					match = true;
					break;
				}
				//do nothing
			}
			
			if(match){
						
						ItemInfo item = new ItemInfo();
						String start = "";
						String end = "";
						String current="";
						java.util.Date d1,d2,d3;
						long minutes=-1;
						long hours=-1;
						long days=-1;
						double currBid;
						
						DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm");
						
						java.util.Date currentDate = new java.util.Date();	
						current = df.format(currentDate);
						
					
						item.itemID = auction.getKey().getId();
						//System.out.println(item.itemID);
			
						item.description = (String) auction.getProperty("DESCRIPTION");
										
						
						item.itemName = (String) auction.getProperty("NAME");
						//System.out.println(item.itemName);
						
						
						//get highest bid 
						Query qBids = new Query("Bid").addFilter("ITEMID", FilterOperator.EQUAL, Long.toString(item.itemID) );
						Iterable<Entity> bids = ds.prepare(qBids).asIterable();
						double maxBid =Double.parseDouble(auction.getProperty("PRICE").toString());
						for(Entity bid : bids )
						{
							currBid = (Double) bid.getProperty("OFFER");
							if(currBid > maxBid){
								maxBid = currBid;
							}
						}
						item.currentBid = maxBid;
						
						
						start =  (String) auction.getProperty("START");
						end =  (String) auction.getProperty("END");
						try {
							
							
							d1 = df.parse(start);
							d2 = df.parse(end);
							d3 = df.parse(current);
							
							 if (d3.after(d2)){
									//do not display, expired
							}else if(d3.before(d1)){
								minutes = (d2.getTime()-d1.getTime())/(1000*60)%60;
								hours = (d2.getTime()-d1.getTime())/(1000*60*60)%24;
								days = (d2.getTime()-d1.getTime())/(1000*60*60*24);
								item.timeLeft = (days + "d" + hours + "h" +minutes+"m");
								
								item.img = "ta1.jpg";
								item.seller = (String) auction.getProperty("SELLER");
								
								list.add(item);
			
							}else{
								minutes = (d2.getTime()-d3.getTime())/(1000*60)%60;
								hours = (d2.getTime()-d3.getTime())/(1000*60*60)%24;
								days = (d2.getTime()-d3.getTime())/(1000*60*60*24);
								item.timeLeft = (days + "d" + hours + "h" +minutes+"m");
								
								item.img = "ta1.jpg";
								item.seller = (String) auction.getProperty("SELLER");
								
								list.add(item);
			
							}
							
						} catch (ParseException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
			}	
		}
								
		return list;
	}

	
	
	public ArrayList<ItemInfo> GetTestData(String category)
	{
		DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
		
		ArrayList<ItemInfo> list = new ArrayList<ItemInfo>();
		
		
		
		//get all auctions associated with this current user
		Query qAuctions = new Query("Auction").addFilter("CATEGORY",FilterOperator.EQUAL , category);
		Iterable<Entity> auctions = ds.prepare(qAuctions).asIterable();
		for(Entity auction : auctions )
		{
				ItemInfo item = new ItemInfo();
				String start = "";
				String end = "";
				String current="";
				java.util.Date d1,d2,d3;
				long minutes=-1;
				long hours=-1;
				long days=-1;
				double currBid;
				
				DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm");
				
				java.util.Date currentDate = new java.util.Date();	
				current = df.format(currentDate);
				
			
				item.itemID = auction.getKey().getId();
				//System.out.println(item.itemID);

				item.description = (String) auction.getProperty("DESCRIPTION");
								
				
				item.itemName = (String) auction.getProperty("NAME");
				//System.out.println(item.itemName);
				
				
				//get highest bid 
				Query qBids = new Query("Bid").addFilter("ITEMID", FilterOperator.EQUAL, Long.toString(item.itemID) );
				Iterable<Entity> bids = ds.prepare(qBids).asIterable();
				double maxBid =Double.parseDouble(auction.getProperty("PRICE").toString());
				for(Entity bid : bids )
				{
					currBid = (Double) bid.getProperty("OFFER");
					if(currBid > maxBid){
						maxBid = currBid;
					}
				}
				item.currentBid = maxBid;
				
				
				start =  (String) auction.getProperty("START");
				end =  (String) auction.getProperty("END");
				try {
					
					
					d1 = df.parse(start);
					d2 = df.parse(end);
					d3 = df.parse(current);
					
					 if (d3.after(d2)){
							//do not display, expired
					}else if(d3.before(d1)){
						minutes = (d2.getTime()-d1.getTime())/(1000*60)%60;
						hours = (d2.getTime()-d1.getTime())/(1000*60*60)%24;
						days = (d2.getTime()-d1.getTime())/(1000*60*60*24);
						item.timeLeft = (days + "d" + hours + "h" +minutes+"m");
						
						item.img = "ta1.jpg";
						item.seller = (String) auction.getProperty("SELLER");
						
						list.add(item);

					}else{
						minutes = (d2.getTime()-d3.getTime())/(1000*60)%60;
						hours = (d2.getTime()-d3.getTime())/(1000*60*60)%24;
						days = (d2.getTime()-d3.getTime())/(1000*60*60*24);
						item.timeLeft = (days + "d" + hours + "h" +minutes+"m");
						
						item.img = "ta1.jpg";
						item.seller = (String) auction.getProperty("SELLER");
						
						list.add(item);

					}
					
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
	
				
			//}
		}
								
		return list;
	}
}
